package com.example.demo.common.result;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.common.enums.CodeEnum;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.ToString;

import java.io.Serializable;
import java.util.Objects;


/**
 * 统一返回结果
 * @author 9523
 * @since 2023-04-24
 */
@Getter
@ToString
@SuppressWarnings("unused")
public class R<T> implements Serializable {

    /**
     * 响应状态（成功1/失败0）
     */
    @JsonProperty(index = 1)
    private Integer code;

    /**
     * 响应消息
     */
    @JsonProperty(index = 3)
    private String msg;

    /**
     * 响应数据
     */
    @JsonProperty(index = 4)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T data;

    /**
     * 无参构造
     */
    @JsonCreator
    public R() {
    }

    /**
     * 私有构造
     *
     * @param code    响应状态（成功1/失败0）
     * @param msg     响应信息
     * @param data    响应数据
//     * @param errCode 错误码
     */
    private R(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
//        this.data = data;
    }

    private R(CodeEnum codeEnum) {
        this.code = codeEnum.getCode();
        this.msg = codeEnum.getMsg();
    }

    /**
     * 请求成功
     *
     * @return RespResult
     */
    public static <T> R<T> success() {
        return new R<>(CodeEnum.SUCCESS);
    }

    /**
     * 请求结果
     *
     * @param result 响应结果
     * @return RespResult
     */
    public static <T> R<T> result(boolean result) {
        if (result) {
            return success();
        } else {
            return fail();
        }
    }

    /**
     * 请求成功
     *
     * @param data 响应数据
     * @return RespResult
     */
    public static <T> R<T> success(T data) {
        return R.<T>success().data(data);
    }

    /**
     * 请求失败
     *
     * @return RespResult
     */
    public static <T> R<T> fail() {
        return new R<>(CodeEnum.FAILURE);
    }

    /**
     * 请求失败
     *
     * @return RespResult
     */
    public static <T> R<T> fail(CodeEnum codeEnum) {
        return new R<>(codeEnum);
    }

    /**
     * 请求失败
     *
     * @param msg 错误消息
     * @return RespResult
     */
    public static <T> R<T> fail(String msg) {
        return R.<T>fail().msg(msg);
    }

    /**
     * 请求失败
     *
     * @param code    状态码
     * @param msg     错误消息
     * @return RespResult
     */
    public static <T> R<T> fail(Integer code, String msg) {
        return R.<T>fail().errCode(code).msg(msg);
    }


//    /**
//     * 请求失败
//     *
//     * @param errCode 错误码
//     * @param msg     错误消息
//     * @return RespResult
//     */
//    public static <T> R<T> fail(Integer errCode, String msg) {
//        return R.<T>fail().errCode(errCode).msg(msg);
//    }

    /**
     * 转为jsonString
     *
     * @return String Json字符串
     */
    public String toJsonString() {
        return JSONObject.toJSONString(this);
    }

    /**
     * 设置错误码
     *
     * @param errCode 错误码
     * @return RespResult
     */
    public R<T> errCode(Integer errCode) {
        this.code = errCode;
        return this;
    }

    /**
     * 设置响应消息
     *
     * @param msg 响应消息
     * @return RespResult
     */
    public R<T> msg(String msg) {
        this.msg = msg;
        return this;
    }

    /**
     * 设置响应数据
     *
     * @param data 响应数据
     * @return RespResult
     */
    public R<T> data(T data) {
        this.data = data;
        return this;
    }

    /**
     * 请求是否成功
     */
    public Boolean succeed() {
        return Objects.equals(this.code, CodeEnum.SUCCESS.getCode());
    }

}
